var tabContainer = null;
var tabList = new Array();
var chatContainerList = new Array();
var handlerList = new Array();
var mainChatContainer = null;
var currentChatContainer = null;
var currentTab = null;

function init() {
    // Tab Container
    tabContainer = getElementByClass("tab-container", document.getElementById("right-column"))[0];

    // Main chat container
    mainChatContainer = document.getElementById("main-chat-container");

    // Init Friend Panel
    FriendPanel.init();

    // Init Room Panel
    RoomPanel.init();

    //
    UserRoomPanel.container = document.getElementById("user-room-container");
}

function ChatBox() {
    
}

ChatBox.onEnter = function(event, element, content) {
    if(event.keyCode == 13) {
        if (ChatBox.isCommand(content)) {
            ChatBox.execCommand(content.substring(1, content.length));
        }
        else if (currentChatContainer) {
            var id = currentChatContainer.id;
            var arr = id.split("-");
            var type = arr[1];
            var recieverId = arr[2];
        
            sendChat(type, userId, recieverId, content);
        }
        
        element.value = "";
    }
}

ChatBox.isCommand = function(content) {
    return content && content.charAt(0) == '/';
}

ChatBox.execCommand = function(command) {
    // Remove space in last
    var newCommand = command.replace(/(  *)$/, "");

    // Split command
    newCommand = newCommand.split(/  */);

    // Validate command
    if (ChatBox.validateCommand(newCommand)) {
        eval("Command." + newCommand[0] + "(newCommand.slice(1))");
    }else {
        alert("Command not found.");
    }
}

ChatBox.validateCommand = function(arrComm) {
    var length = arrComm.length;

    if (length > 0) {
        var first = arrComm[0];

        return  (first == "create"      && (length == 2 || length == 3)) ||
                (first == "join"        && length == 2) ||
                (first == "chat"        && length == 2) ||
                (first == "addfriend"   && length == 2) ||
                (first == "exit"        && length == 1) ||
                (first == "info"        && (length == 2 || length == 1)) ||
                (first == "ban"         && length == 2) ||
                (first == "kick"        && length == 2) ||
                (first == "unban"       && length == 2) ||
                (first == "persist"     && length == 2) ||
                (first == "setowner"    && length == 2);
    }

    return false;
}

/*
 * COMMAND
 */
function Command() {}

Command.create = function (pars) {
    var name = pars[0];
    var categ = pars[1];
    var ajax = new Ajax();

    var URL = baseURL + "/Room?action=create&name="+name;

    if (categ) {
        URL += "&categ="+categ;
    }

    ajax.onLoadSuccess = function() {
        var response = eval("(" + ajax.xhr.responseText + ")");
        if (response.error) {
            alert(response.error);
        } else {
            RoomPanel.getDataAndRender();
            joinChat(response.id, response.name, "room");
        }
    }

    ajax.openAndSend("GET", URL, true);

}

Command.join = function (pars) {
    var name = pars[0];
    
    // Find room
    var room = RoomPanel.find(name);
    
    if (room) {
        // Create Chat
        joinChat(room.id, room.name, "room");
    } else {
        // Not found
        alert("Room not found.")
    }
}

Command.chat = function(pars) {
    var name = pars[0];
    var ajax = new Ajax();

    // On load success
    ajax.onLoadSuccess = function() {
        var user = eval("(" + ajax.xhr.responseText + ")");

        if (user) {
            // Create chat
            joinChat(user.id, user.username, "user");
        } else {
            // Not Found
            alert("username " + name + " not found.")
            return;
        }
    }

    // Send request
    ajax.openAndSend("POST", baseURL + "/User", true, "action=find&username=" + name);
}

Command.exit = function(pars) {
    if(currentTab) {
        closeChat(currentTab);
    }
}

Command.addfriend = function(pars) {
    var username = pars[0];
    
    if (username) {
        var ajax = new Ajax();

        // On load success
        ajax.onLoadSuccess = function() {
            FriendPanel.getDataAndRender();
        }

        // Send request;
        ajax.openAndSend("GET", baseURL + "/Friend?action=addfriend&username=" + username, true);
        
    } else {
        alert("Command not valid.");
    }
}

Command.info = function(pars) {
    var ajax = new Ajax();
    var name = pars[0] || getElementByClass("tab-text", currentTab)[0].innerHTML.replace("#", "");

    ajax.onLoadSuccess = function() {
        alert(ajax.xhr.responseText);
    }

    ajax.openAndSend("GET", baseURL + "/Chat?action=info&name="+name, true);
}

Command.kick = function(pars) {
    var username = pars[0];
    var ajax = new Ajax();
    var roomId = currentTab.id.replace("tab-room-", "");

    ajax.openAndSend("GET", baseURL + "/Room?action=kick&targetUser="+username+"&roomId="+roomId, true);
}

Command.ban = function(pars) {
    var username = pars[0];
    var ajax = new Ajax();
    var roomId = currentTab.id.replace("tab-room-", "");

    ajax.openAndSend("GET", baseURL + "/Room?action=ban&targetUser="+username+"&roomId="+roomId, true);
}

Command.unban = function(pars) {
    var username = pars[0];
    var ajax = new Ajax();
    var roomId = currentTab.id.replace("tab-room-", "");

    ajax.openAndSend("GET", baseURL + "/Room?action=unban&targetUser="+username+"&roomId="+roomId, true);
}

Command.persist = function(pars) {
    var value = pars[0];
    var ajax = new Ajax();
    var roomId = currentTab.id.replace("tab-room-", "");

    ajax.openAndSend("GET", baseURL + "/Room?action=persist&value="+value+"&roomId="+roomId, true);
}

Command.setowner = function(pars) {
    var username = pars[0];
    var ajax = new Ajax();
    var roomId = currentTab.id.replace("tab-room-", "");

    ajax.openAndSend("GET", baseURL + "/Room?action=setowner&targetUser="+username+"&roomId="+roomId, true);
}

/*
 * TAB
 */
function initTab(elementId){
    // Deactive Tab
    var deactiveTabs = getElementByClass("tab", document.getElementById(elementId));

    // Active Tab
    var activeTabs  = getElementByClass("tab active", document.getElementById(elementId));

    // All Tab
    var tabs = deactiveTabs.concat(activeTabs);

    for(var i = 0; i < tabs.length; ++i) {
        // Add Listener
        tabs[i].onclick = function(){
            changeTab(this, elementId);
        };
    }
}

function changeTab(tab, elementId) {
    // Get active tabs
    var tabs = getElementByClass("tab active", document.getElementById(elementId));

    // Deactive all active tabs
    deactiveTab(tabs);

    // Activate clikced tab
    tab.className = "tab active";

    if(elementId == "right-column") {
        currentTab = tab;
    }
}

function deactiveTab(tabs) {
    for(var i = 0; i < tabs.length; ++i) {
        tabs[i].className = "tab";
    }
}

function createTab(id, name, type) {
    tab = document.createElement("div");
    tab.className = "tab active";
    tab.id = "tab-" + type + "-" +id;

    // Create tab name
    tabText = document.createElement("div");
    tabText.className = "tab-text";
    tabText.innerHTML = "#" + name;
    tab.appendChild(tabText);

    // Create tab close action
    tabClose = document.createElement("div");
    tabClose.className = "tab-close";
    tabClose.innerHTML = "x";
    tabClose.onclick = function() {
        closeChat(this.parentNode);
    }
    tab.appendChild(tabClose);

    return tab;
}

/*
 * CHAT
 */
function chatUserListener() {
// Read list Tab

// Send to server POST Request, excluded active tab

// Recieve Respon

// Foreach respon

// If tab is not yet open, call openTab()

// else add chat to coresponden tab
}

function joinChat(id, name, type) {
    if (type == "room") {
        var ajax = new Ajax();

        ajax.onLoadSuccess = function() {
            var success = eval("(" + ajax.xhr.responseText + ")");
            if(success) {
                createChat(id, name, type);
            }
        }

        // Send request
        ajax.openAndSend("POST", baseURL + "/Chat", true, "action=join&roomId=" + id + "&userId=" + userId);
    } else {
        createChat(id, name, type);
    }
}

function unJoinChat(id) {
    var ajax = new Ajax();

    ajax.onLoadSuccess = function() {
        RoomPanel.getDataAndRender();
    }

    // Send
    ajax.openAndSend("GET", baseURL + "/Chat?action=unjoin&roomId="+id, true);
}

function createChat(id, name, type) {
    // Create new Tab
    var tab = createTab(id, name, type);

    // Add tab to list
    tabContainer.appendChild(tab);
    tabList.push(tab);

    // Create new container
    var chatContainer;
    chatContainer = document.createElement("div");
    chatContainer.className = "chat-container";
    chatContainer.id = "container-" + type + "-"+ id;

    if (type == "room") {
        chatContainer.setAttribute("style", "width:500px;");
    }

    // Add container
    changeChatUserContainer(chatContainer);
    chatContainerList.push(chatContainer);

    // Add Listener to tab
    var tabText = getElementByClass("tab-text", tab)[0];
    if (type == "room") {
        tabText.onclick = function() {
            changeTab(this.parentNode, "right-column");
            changeChatRoomContainer(chatContainerList[tabList.indexOf(this.parentNode)]);
        }
    } else {
        tabText.onclick = function() {
            changeTab(this.parentNode, "right-column");
            changeChatUserContainer(chatContainerList[tabList.indexOf(this.parentNode)]);
        }
    }

    // Click it!
    tabText.onclick();

    // Add receive chat listener
    var chatRetriever = new ChatRetriever(id, chatContainer, type);
    handlerList.push(chatRetriever);
    chatRetriever.init();
    chatRetriever.start();
}

function joinUsers(id) {
    var ajax = new Ajax();

    ajax.onLoadSuccess = function() {
        alert(ajax.xhr.responseText);
    }

    // Send request
    ajax.openAndSend("POST", baseURL + "/Chat", true, "action=joinUsers&roomId=" + id + "&userId=" + userId);
}

function changeChatUserContainer(chatContainer) {
    if (currentChatContainer) {
        // Remove old
        mainChatContainer.removeChild(currentChatContainer);
    }

    // Add to main container
    mainChatContainer.appendChild(chatContainer);

    // Update chatContainer
    currentChatContainer = chatContainer;

    UserRoomPanel.container.innerHTML = "";

    // Delete chatroomcontainer
    if (UserRoomPanel.currentObject) {
        UserRoomPanel.currentObject.close();
    }
}

function changeChatRoomContainer(chatContainer) {
    changeChatUserContainer(chatContainer);

    var roomId = chatContainer.id.replace("container-room-", "");
    UserRoomPanel.container.setAttribute("style", "width:50px;");

    UserRoomPanel.currentObject = new UserRoomPanel(roomId);
    UserRoomPanel.currentObject.init();
}

function sendChat(type, senderId, recieverId, content) {
    var ajax = new Ajax();

    // Send Chat
    ajax.openAndSend("POST", baseURL + "/Chat", true, "type=" + type + 
        "&action=send&content=" + content + "&senderId=" + senderId +
        "&recieverId=" + recieverId);
}

function closeChat(tab) {
    if (tab) {
        // Get index of tab
        var index = tabList.indexOf(tab);

        // Close and remove handler
        handlerList[index].close();
        handlerList.splice(index, 1);

        // Remove tab
        tabContainer.removeChild(tab);
        tabList.splice(index, 1);

        // Remove container
        chatContainerList.splice(index, 1);

        // Unjoin chat
        var split = tab.id.split("-");
        if (split[1] == "room") {
            // Unjoin chat
            unJoinChat(split[2]);
        }

        if (currentTab == tab) { // Closed tab is current tab

            // Get next tab or prev tab
            var t = tabList[index] || tabList[index-1];
            
            if (t) { // Other tab is exist

                // Get tab text
                var tabText = getElementByClass("tab-text", t)[0];

                // Click tab text
                tabText.onclick();

            } else { // No tabs anymore

                // Remove chat container
                mainChatContainer.removeChild(currentChatContainer);

                // Reset current chat container and current tab
                currentChatContainer = null;
                currentTab = null;
                UserRoomPanel.container.innerHTML = "";
            }
        }
    }
}

/**
 * Chat Retriever
 */
function ChatRetriever(id, container, type) {
    this.id = id;
    this.lastId = -1;
    this.container = container;
    this.timeoutId = 0;
    this.delay = 1000;
    this.type = type;
    var self = this;

    this.init = function() {
        this.ajax = new Ajax();
    }

    this.start = function() {
        self.timeoutId = window.setTimeout(self.listen, self.delay);
    //self.timeoutId = window.setInterval(self.listen, self.delay);
    }

    this.listen = function() {
        // Create ajax
        var ajax = new Ajax();
        ajax.handler = self;

        ajax.onLoadSuccess = function() {
            // Recieve data
            var json = this.xhr.responseText;
            var chats = eval(json);
            var chat;

            if (chats) {
                for (var i = 0; i <chats.length; ++i) {
                    chat = chats[i];
                    this.handler.addToChatContainer(chat.senderName + " : " + chat.content);
                    this.handler.lastId = chat.id;
                }
            }

            // Listen again
            self.start();
        }

        // Request data
        ajax.openAndSend("POST", baseURL + "/Chat", true, "type=" + self.type + "&action=recieve&id=" + self.id + "&lastId=" + self.lastId);
    }

    this.addToChatContainer = function(response) {
        // Create chat-text element
        var chatText = document.createElement("div");
        chatText.className = "chat-text"
        chatText.innerHTML = response;

        // Add to container
        this.container.appendChild(chatText);

        // Set scroll
        var con = this.container;
        con.scrollTop = con.scrollHeight;
    }

    this.close = function() {
        window.clearInterval(self.timeoutId);
    }
}


/**
 * Friend Panel Class
 */
function FriendPanel() {
    
}

FriendPanel.onlineList = false;
FriendPanel.data = null;
FriendPanel.timeoutId = null;

FriendPanel.init = function() {    
    FriendPanel.getDataAndRender();
}

FriendPanel.showOnline = function() {
    FriendPanel.clearTimeout();
    FriendPanel.onlineList = true;
    FriendPanel.getDataAndRender();
}

FriendPanel.showAll = function() {
    FriendPanel.clearTimeout();
    FriendPanel.onlineList = false;
    FriendPanel.getDataAndRender();
}

FriendPanel.setTimeout = function() {
    FriendPanel.timeoutId = window.setTimeout(function(){
        FriendPanel.getDataAndRender()
    }, 10000);
}

FriendPanel.clearTimeout = function() {
    window.clearTimeout(FriendPanel.timeoutId);
}

FriendPanel.getDataAndRender = function() {
    FriendPanel.clearTimeout();
    
    // Create ajax
    var ajax = new Ajax();

    // Event listener on load success
    ajax.onLoadSuccess = function() {
        FriendPanel.data = eval("(" + ajax.xhr.responseText + ")");
        FriendPanel.render();

        // Call again
        FriendPanel.setTimeout();
    }

    // Send
    ajax.openAndSend("GET", baseURL + "/Friend?action=get", true, null);
}

FriendPanel.render = function() {
    var friends = getElementByClass("friends", document.getElementById("friends-panel"))[0];
    var data = FriendPanel.data;

    // Clear
    friends.innerHTML = "";
    
    for (var i = 0; i < data.length; ++i) {
        var friend = data[i];
        
        if (!FriendPanel.onlineList || friend.online) {
            var friendEl = document.createElement("div");
            var inner = '<img src="" alt="' + ((friend.online) ? "on" : "off") + '" class="status" />\n' + '<div class="friend-name">' + friend.username + '</div>';
        
            friendEl.className = "friend";
            friendEl.id = "friend-user-" + friend.id;
            friendEl.innerHTML = inner;

            // Add Event On Click
            friendEl.onclick = function() {
                var id = this.id.replace("friend-user-", "");
                var name = getElementByClass("friend-name", this)[0].innerHTML;
                joinChat(id, name, "user");
            }

            // Add to conatiner
            friends.appendChild(friendEl);
        }
    }
}


/*
 * Room Panel Class
 */
function RoomPanel() {
    
}

RoomPanel.data = null;
RoomPanel.rooms = new Array();

RoomPanel.init = function() {
    RoomPanel.getDataAndRender();
}

RoomPanel.setTimeout = function() {
    RoomPanel.timeoutId = window.setTimeout(RoomPanel.getDataAndRender, 10000);
}

RoomPanel.clearTimeout = function() {
    window.clearTimeout(RoomPanel.timeoutId);
}

RoomPanel.getDataAndRender = function() {
    RoomPanel.clearTimeout();

    // Create ajax
    var ajax = new Ajax();

    // Event listener on load success
    ajax.onLoadSuccess = function() {
        RoomPanel.data = eval("(" + ajax.xhr.responseText + ")");
        RoomPanel.rooms = new Array();
        RoomPanel.render(RoomPanel.data, true);

        // Call again
        RoomPanel.setTimeout();
    }

    // Send
    ajax.openAndSend("GET", baseURL + "/Room?action=listRoom", true);
}

RoomPanel.onclickHandler = function(element) {
    var id = element.id.replace("room-", "");
    joinChat(id, element.innerHTML, "room");
}

RoomPanel.render = function(category, first) {
    var categories = category.subCategories;
    var rooms = category.rooms;
    var inner = "";
    var i;

    if(!first) {
        inner += '<div class="category-name">' + category.name + '</div>\n';
    }

    for (i = 0; i < rooms.length; ++i) {
        var room = rooms[i];
        RoomPanel.rooms.push(room);
        inner += '<div onclick="RoomPanel.onclickHandler(this);" id="room-' + room.id + '" class="room">' + room.name + '</div>\n';
    }

    for (i = 0; i < categories.length; ++i) {
        var categ = categories[i];
        inner += '<div class="category">\n';
        inner += RoomPanel.render(categ, false);
        inner += '\n</div>\n';
    //alert(inner);
    }

    if (first) {
        document.getElementById("room-panel").innerHTML = inner;
    } else {
        return inner;
    }

    return "";
}

RoomPanel.find = function(name) {
    var rooms = RoomPanel.rooms;
    
    if (rooms) {
        for (var i=0; i < rooms.length; ++i) {
            if (rooms[i].name == name) {
                // Found
                return rooms[i];
            }
        }
    }

    // Not found
    return null;
}

/*
 * User Room Panel Class
 */
function UserRoomPanel(roomId) {
    this.roomId = roomId;
    this.timeoutId = null;
    this.data = null;
    this.kickListener = new UserRoomKick(roomId);

    var self = this;

    this.init = function() {
        self.getDataAndRender();
        self.kickListener.init();
    }

    this.setTimeout = function() {
        self.timeoutId = window.setTimeout(self.getDataAndRender, 10000);
    }

    this.clearTimeout = function() {
        if (self.timeoutId) {
            window.clearTimeout(self.timeoutId);
        }
    }

    this.render = function() {
        var data = self.data;
        UserRoomPanel.container.innerHTML = "";

        for (var i = 0; i < data.length; ++i) {
            var user = data[i];
            var roomUser = document.createElement("div");
            roomUser.className = "room-user";
            roomUser.id = "room-user-" + user.id;
            roomUser.innerHTML = user.username;

            // Add Event On Click
            roomUser.onclick = function() {
                var id = this.id.replace("room-user-", "");
                var name = this.innerHTML;
                joinChat(id, name, "user");
            }

            // Add to container
            UserRoomPanel.container.appendChild(roomUser);
        }
    }

    this.getDataAndRender = function() {
        var ajax = new Ajax();

        ajax.onLoadSuccess = function() {
            self.data = eval("(" + ajax.xhr.responseText + ")");
            self.render();

            // Call again
            self.setTimeout();
        }

        ajax.openAndSend("GET", baseURL + "/Room?action=listUser&roomId="+self.roomId, true);
    }

    this.close = function() {
        self.clearTimeout();
        self.kickListener.close();
    }
}

UserRoomPanel.currentPanel = null;
UserRoomPanel.currentObject = null;
UserRoomPanel.container = null;

/*
 * User Room Kicked
 */
function UserRoomKick(roomId, tabClose) {
    this.roomId = roomId;
    this.timeoutId = null;
    this.tabClose = null;
    var self = this;

    this.init = function() {
        self.setTabClose();
        self.listen();
    }

    this.setTabClose = function() {
        var tab = document.getElementById("tab-room-" + self.roomId);
        self.tabClose = getElementByClass("tab-close", tab)[0];
    }
    
    this.listen = function() {
        var ajax = new Ajax();

        ajax.onLoadSuccess = function() {
            var kick = eval("(" + ajax.xhr.responseText + ")");

            if (kick) {
                self.clearTimeout();
                // Close
                self.tabClose.onclick();
            } else {
                self.setTimeout();
            }
        }

        ajax.openAndSend("GET", baseURL + "/Room?action=iskick&roomId=" + self.roomId, true);
    }

    this.setTimeout = function() {
        self.timeoutId = window.setTimeout(self.listen, 3000);
    }

    this.clearTimeout = function() {
        window.clearTimeout(self.timeoutId);
    }

    this.close = function() {
        self.clearTimeout();
    }
}